var gamejs = require('gamejs');

var Enemy = require('js/enemy').Enemy;
var Map = require('js/map').Map;
var Match = require('js/match').Match;
var Obstacle = require('js/obstacle').Obstacle;
var Radar = require('js/radar').Radar;
var Turret = require('js/turret').Turret;
var Projectile = require('js/projectile').Projectile;

var preload = require('js/preload');

// Some constants
var WIDTH = 800;
var HEIGHT = 480;

// Preload of resources
preload.preload();

gamejs.ready(main);

/**
 * The main
 */
function main() {

	// Initialize gamejs stuff
	gamejs.display.setMode([WIDTH, HEIGHT]);
	var gameSurface = gamejs.display.getSurface();
	
	// Loads the menu images
	var menu = gamejs.image.load(IMAGE_ROOT + 'menu.png');
	var instructions = gamejs.image.load(IMAGE_ROOT + 'instructionsEx.png');
	var add = gamejs.image.load(IMAGE_ROOT + 'add.png');
	var modify = gamejs.image.load(IMAGE_ROOT + 'action.png');
	var menuBackground = menu;
	var actionImage = add;
	
	var gameStarted = false;
	var instructionStarted = false;
	var addPressed = false;
	var modifyPressed = false;

	// The coordinates of the point in which the player clicks with the mouse
	var xPoint = 0;
	var yPoint = 0;
	
	// Offsets of the action selection box menu
	var x = 98;  // orizontal dimention of the selection box
	var y1 = 32; // vertical dimention of the first frame of the selection box
	var y2 = 28; // vertical dimention of the second frame of the selection box
	var y3 = 31; // vertical dimention of the third frame of the selection box
	
	// called on every refresh
	var tick = function(msDuration) {
		var events;
		if (instructionStarted) {
			menuBackground = instructions;
		}
		if ( ! gameStarted) {
			gameSurface.blit(menuBackground, [0, 0]);
			
			// Reads the mouse imput event
			events = gamejs.event.get();
			
			events.forEach(function(event) {
				// Passes only by clicking on "New game"
				if (event.type == gamejs.event.MOUSE_UP &&
						! instructionStarted &&
						((event.pos[0] <= 300 && event.pos[0] >= 88) &&
						(event.pos[1] <= 352 && event.pos[1] >=312))) {
					instructionStarted = true;
					return;
				}
				
				// Starts the game after reading instructions
				// Passes only by clicking start game
				if (event.type == gamejs.event.MOUSE_UP &&
						instructionStarted &&
						((event.pos[0] <= 776 && event.pos[0] >= 608) &&
						(event.pos[1] <= 424 && event.pos[1] >=360))) {
					gameStarted = true;
					instructionStarted = false;
					return;
				}
				
				// Passes only by clicking on "Credits"
				if (event.type == gamejs.event.MOUSE_UP &&
						! instructionStarted &&
						((event.pos[0] <= 252 && event.pos[0] >= 88) &&
						(event.pos[1] <= 398 && event.pos[1] >=358))) {
					//Does nothing for now
					return;
				}
				
				// Passes only by clicking on "Exit"
				if (event.type == gamejs.event.MOUSE_UP &&
						! instructionStarted &&
						((event.pos[0] <= 172 && event.pos[0] >= 88) &&
						(event.pos[1] <= 445 && event.pos[1] >=405))) {
					//Does nothing for now
					return;
				}
			});
			return;
		}
		
		// Starts and evolves the game updating its statuses every refresh
		map.update(msDuration);
		match.update(msDuration);
		map.draw(gameSurface);
		match.draw(gameSurface);
		
		// All the actions that can be done during the game
		if (gameStarted){
			// Reads the mouse imput event
			events = gamejs.event.get();
			
			// Finds out if i'm pressing on an existing object or on an
			// unfilled place of the map
			events.forEach(function(event) {
				if (event.type == gamejs.event.MOUSE_UP &&
						! addPressed &&
						! modifyPressed) {
					if ( ! map.isFilled([event.pos[0], event.pos[1]]) ) {
						addPressed = true;
						actionImage = add;
					}
					else {
						modifyPressed = true;
						actionImage = modify;
					}
					xPoint = event.pos[0];
					yPoint = event.pos[1];
					return;
				}
				
				// if the add box is open do:
				if (event.type == gamejs.event.MOUSE_UP && addPressed ) {
					if ((match.getCredit() >= Radar.BUY_PRICE) &&
							(event.pos[0] >= xPoint && event.pos[0] <= (xPoint + x)) &&
							(event.pos[1] >= yPoint && event.pos[1] <= (yPoint + y1))){
						// Adds a radar on the map
						map.addRadar(new Radar(match, [xPoint, yPoint]));
						// Reduces the credit by the radar cost
						match.changeCredit(- Radar.BUY_PRICE);
						addPressed = false;
					}
					else if ((match.getCredit() >= Turret.BUY_PRICE) &&
							(event.pos[0] >= xPoint && event.pos[0] <= (xPoint + x)) &&
							(event.pos[1] > (yPoint + y1) && event.pos[1] <= (yPoint + (y1 + y2)))){
						// Adds a turret on the map
						map.addTurret(new Turret(match, [xPoint, yPoint]));
						// Reduces the credit by the turret cost
						match.changeCredit(- Turret.BUY_PRICE);
						addPressed = false;
					}
					else if ((event.pos[0] >= xPoint && event.pos[0] <= (xPoint + x)) &&
							(event.pos[1] > (yPoint + (y1 + y2)) && event.pos[1] <= (yPoint + (y1 + y2 + y3)))) {
						// Add an obstacle on the map
						map.addObstacle(new Obstacle(match, [xPoint, yPoint], 40));
						addPressed = false;
					}
					else {
						addPressed = false;
					}
					
				}
				
				// if the modify box is open do:
				// Pressing on upgrade
				var turret, radar;
				if (event.type == gamejs.event.MOUSE_UP && modifyPressed) {
					if ((event.pos[0] >= xPoint && event.pos[0] <= (xPoint + x)) &&
							(event.pos[1] >= yPoint && event.pos[1] <= (yPoint + y1))) {
						// Checks which object is placed in the selected point
						radar = map.radars.collidePoint([xPoint, yPoint]);
						turret = map.turrets.collidePoint([xPoint, yPoint]);
						modifyPressed = false;
						if (radar.length !== 0 &&
								match.getCredit() >= radar[0].getUpgradePrice()
							) {
							// If radar do:
							match.changeCredit(- radar[0].getUpgradePrice());
							radar[0].upgrade();
						}
						else if (turret.length !== 0 &&
								match.getCredit() >= turret[0].getUpgradePrice()
							) {
							// If turret do:
							match.changeCredit(- turret[0].getUpgradePrice());
							turret[0].upgrade();
						}
					}
					// Pressing on sell
					else if ((event.pos[0] >= xPoint && event.pos[0] <= (xPoint + x)) &&
							(event.pos[1] > (yPoint + y1) && event.pos[1] <= (yPoint + (y1 + y2)))){
						// Checks which object is placed in the selected point
						radar = map.radars.collidePoint([xPoint, yPoint]);
						turret = map.turrets.collidePoint([xPoint, yPoint]);
						modifyPressed = false;
						if (radar.length !== 0) {
							// If radar do:
							match.changeCredit(radar[0].getResaleValue());
							map.removeRadar(radar[0]);
						}
						else {
							// If turret do:
							match.changeCredit(turret[0].getResaleValue());
							map.removeTurret(turret[0]);
						}
					}
					else {
						modifyPressed = false;
					}
				}
			});
			
			// dispalys the add box
			if(addPressed){
				gameSurface.blit(actionImage, [xPoint, yPoint]);
			}
			
			// displays the modify box
			if(modifyPressed){
				gameSurface.blit(actionImage, [xPoint, yPoint]);
			}
		}
	};

	// Create Match and Map Objects
	var match = new Match();
	var map = new Map(match, WIDTH, HEIGHT);
	match.setMap(map);

	// Create enemies
	map.addEnemy(new Enemy(match, [WIDTH - 1, 120]));
	map.addEnemy(new Enemy(match, [WIDTH - 1, 121]));
	map.addEnemy(new Enemy(match, [WIDTH - 1, 122]));
	map.addEnemy(new Enemy(match, [WIDTH - 1, 123]));
	map.addEnemy(new Enemy(match, [WIDTH - 1, 134]));
	map.addEnemy(new Enemy(match, [WIDTH - 1, 155]));
	map.addEnemy(new Enemy(match, [WIDTH - 1, 186], 1));
	map.addEnemy(new Enemy(match, [WIDTH - 1, 201], 1));
	map.addEnemy(new Enemy(match, [WIDTH - 1, 215], 1));
	map.addEnemy(new Enemy(match, [WIDTH - 1, 230], 1));
	map.addEnemy(new Enemy(match, [WIDTH - 1, 240], 1));
	map.addEnemy(new Enemy(match, [WIDTH - 1, 360], 1));

	// Create radars
	map.addRadar(new Radar(match, [200, 160]));
	map.addRadar(new Radar(match, [200, 320], Math.PI, Math.PI));
	var upgradedRadar = new Radar(match, [600, 90]);
	upgradedRadar.upgrade();
	map.addRadar(upgradedRadar);

	// Create obstacles
	map.addObstacle(new Obstacle(match, [230, 40]));
	map.addObstacle(new Obstacle(match, [400, 100], 1));
	map.addObstacle(new Obstacle(match, [300, 360], 2));

	// Create turrets
	map.addTurret(new Turret(match, [550, 190]));
	var upgradedTurret = new Turret(match, [100, 160]);
	upgradedTurret.upgrade();
	map.addTurret(upgradedTurret);

	gamejs.time.fpsCallback(tick, this, 60);

}